﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PartitionsCodegen
{
    class CNCFigure
    {
        private CNCInstruction[] instructions;
       
        //Constructor method for original code
        public CNCFigure(string s_code, decimal offset_x, decimal offset_y, float depth)
        {
            instructions = parseInstructions(s_code);
            adjustoffsets(offset_x, offset_y);
        }

        //Constructor method for copies
        public CNCFigure(CNCFigure original, int i, decimal size, float z, bool to_the_right)
        {
            instructions = parseInstructions(original.getString());
            adjustposition(i,size,z,to_the_right);
        }

        private void adjustoffsets(decimal x, decimal y)
        {
            for (int i = 0; i < instructions.Length; i++)
            {
                instructions[i].adjustOffset(x, y);
            }
        }

        private void adjustposition(int ncopy, decimal size, float z, bool to_the_right)
        {
            for (int i = 0; i < instructions.Length; i++) {
                instructions[i].adjustPosition(ncopy,size,z,to_the_right);
            }
        }

        private CNCInstruction[] getinstructions()
        {
            return instructions;
        }

        //Parser from string to intructions
        private CNCInstruction[] parseInstructions(string s_code)
        {
            List<CNCInstruction> lInstructions = new List<CNCInstruction>();
            String aLine;
            System.IO.StringReader reader = new System.IO.StringReader(s_code);
            CNCInstruction cncins;

            while ((aLine = reader.ReadLine()) != null)
            {
                cncins = new CNCInstruction(aLine.Trim());
                lInstructions.Add(cncins);
            }
            return lInstructions.ToArray();
        }

        public string getString()
        {
            int nInstructions = instructions.Length;
            String[] stringInstructions = new string[nInstructions];
            
            for (int i = 0; i < nInstructions; i++)
            {
                stringInstructions[i] = instructions[i].getString();
            }
            return String.Join("\r\n", stringInstructions); 
        }
 
        public decimal calculate_size_X()
        {
            int nInstructions = instructions.Length;
            decimal min = 9999;
            decimal max = 0;

            if (instructions[0].hasXValue())
            {
                min = instructions[0].getPosX();
                max = instructions[0].getPosX();
            }
            decimal posX = 0;

            for (int i = 1; i < nInstructions; i++)
            {
                if (instructions[i].hasXValue()){
                    posX = instructions[i].getPosX();
                    if (min > posX) min = posX;
                    if (max < posX) max = posX;
                }
            }
            return max-min;
        }

        public decimal calculate_size_Y()
        {
            int nInstructions = instructions.Length;
            decimal min = 9999;
            decimal max = 0;

            if (instructions[0].hasYValue())
            {
                min = instructions[0].getPosY();
                max = instructions[0].getPosY();
            }
            decimal posY = 0;

            for (int i = 1; i < nInstructions; i++)
            {
                if (instructions[i].hasYValue())
                {
                    posY = instructions[i].getPosY();
                    if (min > posY) min = posY;
                    if (max < posY) max = posY;
                }
            }
            return max - min;
        }

        public decimal getStartingX()
        {
            int nInstructions = instructions.Length;
            decimal startX = 0;
            bool b = false;
            int i = 0;

            while (!b && i < nInstructions )
            {
                if (instructions[i].hasXValue())
                {
                    b = true;
                    startX = instructions[i].getPosX();
                }
            }
            return startX;
        }

        public decimal getStartingY()
        {
            int nInstructions = instructions.Length;
            decimal startY = 0;
            bool b = false;
            int i = 0;

            while (!b && i < nInstructions)
            {
                if (instructions[i].hasYValue())
                {
                    b = true;
                    startY = instructions[i].getPosY();
                }
            }
            return startY;
        }
    }
}